<?php
/**
 * Created by PhpStorm.
 * Script Name: Tpzs.php
 * Create: 2022/4/18 10:38
 * Description: 推品助手处理器
 * Author: fudaoji<fdj@kuryun.cn>
 */

namespace app\bot\controller;

use app\common\model\ai\Config;
use ky\Logger;
use ky\OpenAI\Base;

class Ai extends Addon
{
    private $configs;
    private $toWxid = '';
    /**
     * @var Config
     */
    private $configM;
    /**
     * @var \ky\OpenAI\Driver\Weixin
     */
    private $aiClient;

    public function init($options = [])
    {
        parent::init($options); // TODO: Change the autogenerated stub
        $this->configM = new Config();
        $this->configs = $this->configM->getConf(['bot_id' => $this->bot['id']]);
        return $this;
    }

    /**
     * 机器人主动事件
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * Author: fudaoji<fdj@kuryun.cn>
     */
    public function deviceCallbackHandle(){
        if(!empty($this->groupWxid)){
            //$this->groupChatHandle();
        }
    }

    /**
     * 群聊处理器
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function groupChatHandle(){
        $this->toWxid = $this->groupWxid;
        if(!$this->groupChatCheck()){
            return false;
        }
        //一、关键词
        $this->keyword();
    }

    private function groupChatCheck(){
        if(!$this->workTimeCheck() || $this->fromWxid == $this->botWxid
            || (!empty($this->configs['need_at']) && (strpos($this->content['msg'], $this->beAtStr[0]) === false
                && strpos($this->content['msg'], $this->beAtStr[1]) === false))){
            return false;
        }
        return true;
    }

    /**
     * 工作时间检验
     * @return bool
     * Author: fudaoji<fdj@kuryun.cn>
     */
    private function workTimeCheck(){
        if(empty($this->configs['switch']) || strpos($this->configs['wxids'], $this->toWxid) === false){
            return false;
        }
        if(empty($this->configs['time_on']) || empty($this->configs['time_off'])){
            return true;
        }
        return  date('H:i:s') >= $this->configs['time_on'] && date('H:i:s') <= $this->configs['time_off'];
    }

    /**
     * 私聊处理器
     * Author: fudaoji<fdj@kuryun.cn>
     */
    public function privateChatHandle(){
        $this->toWxid = $this->fromWxid;
        if(!$this->privateChatCheck()){
            return false;
        }
        //一、关键词
        $this->keyword();
    }

    private function privateChatCheck(){
        if(! $this->workTimeCheck()){
            return false;
        }
        return true;
    }

    /**
     * 关键词回复
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * Author: fudaoji<fdj@kuryun.cn>
     */
    private function keyword(){
        $this->aiClient = $this->configM->getAiClient($this->bot, $this->configs['driver']);
        $msg = str_replace($this->beAtStr, "", trim($this->content['msg']));
        if($msg == 'checkkey'){
            $content = $this->aiClient->checkKey();
            $this->botClient->sendTextToFriend([
                'robot_wxid' => $this->botWxid,
                'to_wxid' => $this->toWxid,
                'msg' => json_encode($content, JSON_UNESCAPED_UNICODE)
            ]);
            return true;
        }
        $content_rule = $this->configs['content_rule'] ?? '';
        $background = $this->configs['character_design'] ?? '';
        $context = $this->getContext(md5($this->botWxid.$this->groupWxid.$this->fromWxid));

        $res = $this->aiClient->smart([
            'userid' => $this->fromWxid,
            'msg' => $msg,
            'content_rule' => $content_rule,
            'background' => $background,
            'context' => $context,
        ]);
        //Logger::error($context);
        if($res['code'] && !empty($res['answer_type'])){
            switch ($res['answer_type']){
                case Base::ANSWER_TEXT:
                    $answer = (!empty($this->configs['show_question']) ? ($msg . "\n----------------\n") :'') . $res['answer'];
                    if(empty($this->groupWxid) || empty($this->configs['need_at'])){
                        $this->botClient->sendTextToFriend([
                            'robot_wxid' => $this->botWxid,
                            'to_wxid' => $this->toWxid,
                            'msg' => $answer
                        ]);
                    }else{
                        $this->botClient->sendGroupMsgAndAt([
                            'group_wxid' => $this->groupWxid,
                            'robot_wxid' => $this->botWxid,
                            'member_wxid' => $this->fromWxid,
                            'msg' => $answer
                        ]);
                    }
                    break;
                case Base::ANSWER_MUSIC:
                    $answer = '';
                    if(!empty($res['more_info']['music_ans_detail'])){
                        $res['more_info']['music_ans_detail'] = json_decode($res['more_info']['music_ans_detail'], true);
                        if(!empty($res['more_info']['music_ans_detail']['play_command']['play_list'])){
                            $info = $res['more_info']['music_ans_detail']['play_command']['play_list'][0];
                            $this->botClient->sendMusicLinkMsg([
                                'robot_wxid' => $this->botWxid,
                                'to_wxid' => $this->toWxid,
                                'title' =>  $info['name'],  // 标题
                                'desc' => $info['author'],  // 内容
                                'url' => "https://y.qq.com/n/ryqq/songDetail/{$info['mid']}",  // 链接地址
                                'dataurl' => $info['url'], // mp3地址
                                'thumburl' => $info['album_pic_url'],  // http图片地址
                            ]);
                        }
                    }
                    break;
                default:
                    $answer = (!empty($this->configs['show_question']) ? ($msg . "\n----------------\n") :'') . $res['answer'];
                    if($answer){
                        $this->botClient->sendTextToFriend([
                            'robot_wxid' => $this->botWxid,
                            'to_wxid' => $this->toWxid,
                            'msg' => $answer
                        ]);
                    }
                    break;
            }
            $this->getContext(md5($this->botWxid.$this->groupWxid.$this->fromWxid), $msg, $res['answer']);
        }
    }

    /**
     * 获取或设置上下文
     * @param string $cache_key
     * @param string $msg_user
     * @param string $msg_bot
     * @return array|mixed
     * Author: fudaoji<fdj@kuryun.cn>
     */
    private function getContext($cache_key = '', $msg_user = "", $msg_bot = ""){
        $context = cache($cache_key);
        if(empty($context)){
            $context = [];
        }else{
            $context = json_decode($context, true);
        }
        $len = $this->configs['context_length'] ?? 10;
        if(count($context) >= $len){
            array_shift($context);
        }
        if(!empty($msg_user)){
            array_push($context, ["role" => "user", "content" => $msg_user]);
        }
        if(!empty($msg_bot)){
            array_push($context, ["role" => "assistant", "content" => $msg_bot]);
        }
        cache($cache_key, json_encode($context), 86400);
        return $context;
    }
}